package com.tai.cobrapp.backend;

import java.util.ArrayList;


import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import com.google.gson.Gson;
import com.tai.cobrapp.database.DatabaseHelper;
import com.tai.cobrapp.model.DetalleRelevamiento;
import com.tai.cobrapp.model.Dispositivo;
import com.tai.cobrapp.model.Establecimiento;
import com.tai.cobrapp.model.Relevamiento;

import android.content.Context;
import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.util.Log;

	
public class Backend extends Object
{
	private static Backend instance;
	
	private Backend(){}
	
	// Singleton
	public static Backend getInstance()
	{
		createInstance();
		return instance;		
	}	
	
	private static synchronized void createInstance(){
		if(instance == null)
		{
			instance = new Backend();
		}
	}
	
	public ArrayList<DetalleRelevamiento> getDetailedSurvey(Integer option, Context context){			
		return DatabaseHelper.getDatabaseInstance(context).ListDetalleRelevamiento(option);
	}
	
	public ArrayList<Relevamiento> ListSurveys(Integer option, Context context){
			return DatabaseHelper.getDatabaseInstance(context).ListRelevamientos(option);
	}
	public String obtenerUserPassword(Context context, Editable name){
		return DatabaseHelper.getDatabaseInstance(context).getUserPass(name);
	}
	/* METODOS PARA ESTABLECIMIENTO */
	public ArrayList<Establecimiento> getEstablecimientos(Integer option, Context context){
		return DatabaseHelper.getDatabaseInstance(context).ListEstablecimientos(option);
	}
	public ArrayList<Establecimiento> getActiveEstablecimientos(Integer option, Context context){
		return DatabaseHelper.getDatabaseInstance(context).ListActiveEstablecimientos(option);
	}
	public boolean bkEndchkEstabExists(Context context){
		return DatabaseHelper.getDatabaseInstance(context).HayEstablecimientos();
	}
	public boolean bkEndchkActiveEstabExists(Context context){
		return DatabaseHelper.getDatabaseInstance(context).HayEstablecimientosActivos();
	}
	public void updateEstablishment(Context context, Establecimiento establ){
		DatabaseHelper.getDatabaseInstance(context).ActualizarEstablecimiento(establ);
	}
	public Boolean existeEstablecimiento(Context context, Editable establishment){
		return DatabaseHelper.getDatabaseInstance(context).existeEstablecimiento(establishment);
	}
	public Boolean existeOtroEstablecimiento(Context context, Editable nombreBase, Editable establishment){
		return DatabaseHelper.getDatabaseInstance(context).existeOtroEstablecimiento(nombreBase, establishment);
	}
	/* FIN METODOS PARA ESTABLECIMIENTO */
	/* METODOS PARA DISPOSITIVO */
	public boolean bkEndchkDevicesExists(Context context, Integer idEstablecimiento){
		return DatabaseHelper.getDatabaseInstance(context).HayDispositivos(idEstablecimiento);
	}
	public ArrayList<Dispositivo> getActiveDispositivos(Integer idEstablecimiento, Context context){
		// HACER LA CONSULTA FILTRADA POR EL ID DE ESTABLECIMIENTO
		if (idEstablecimiento == null){
			return DatabaseHelper.getDatabaseInstance(context).ListActiveDispositivos();
		}else{
			return DatabaseHelper.getDatabaseInstance(context).GetActiveDipositivosByIdEstablecimiento(idEstablecimiento);
		}
	}
	public ArrayList<Dispositivo> getDispositivos(Integer idEstablecimiento, Context context){
		// HACER LA CONSULTA FILTRADA POR EL ID DE ESTABLECIMIENTO
		if (idEstablecimiento == null){
			return DatabaseHelper.getDatabaseInstance(context).ListDispositivos();
		}else{
			return DatabaseHelper.getDatabaseInstance(context).GetDipositivosByIdEstablecimiento(idEstablecimiento);
		}
	}
	public void updateDevice(Context context, Dispositivo device){
		DatabaseHelper.getDatabaseInstance(context).ActualizarDispositivo(device);
	}
	public Boolean existeDispositivo(Context context, Editable device){
		return DatabaseHelper.getDatabaseInstance(context).existeDispositivo(device);
	}
	public Boolean existeOtroDispositivo(Context context, Editable nombreBase, Editable device){
		return DatabaseHelper.getDatabaseInstance(context).existeOtroDispositivo(nombreBase, device);
	}
	/* FIN METODOS PARA DISPOSITIVO */
	/* METODOS PARA DETALLE RELEVAMIENTO */
	public void insertSurveyDetail(Context context, ArrayList<DetalleRelevamiento> detalleList, Integer idRelev)
    {	
    	DatabaseHelper.getDatabaseInstance(context).insertarDetalleRelevamiento(detalleList, idRelev);
    }
	/* FIN METODOS PARA DETALLE RELEVAMIENTO */
	/* METODOS PARA RELEVAMIENTO */
	public Integer insertSurvey(Context context, Relevamiento relev)
    {
    	return DatabaseHelper.getDatabaseInstance(context).insertarRelevamiento(relev);
    }
	public Boolean existeRelevamiento(Context context, Editable name)
    {	
    	return DatabaseHelper.getDatabaseInstance(context).existeRelevamiento(name);
    }
	public Boolean tieneRelevamientos(Context context, Integer idUser)
    {	
    	return DatabaseHelper.getDatabaseInstance(context).tieneRelevamientos(idUser);
    }
	/* FIN METODOS PARA DETALLE RELEVAMIENTO */
	
	
		
	public Boolean getEstabAndDispFromServerWithGSON(Context context)
	//public void getEstablecimientosWithGSON()
	{
		InputStreamReader response = getFromServer();
		if(response != null)
		{	
			Gson gson = new Gson();
			
			EstablecimientoVO[] dbEstab = gson.fromJson(response, EstablecimientoVO[].class);
			
			Establecimiento establecimiento = null;
			Dispositivo dispositivo = null;
			Integer idEstab = -1;
			for (EstablecimientoVO dbEstabItem : dbEstab) {
				//Log.d("Establ.", dbEstabItem.getName().toString());
				if (!existeEstablecimiento(context, new SpannableStringBuilder(dbEstabItem.getName()))){
					establecimiento = new Establecimiento(new SpannableStringBuilder(dbEstabItem.getName()), new SpannableStringBuilder(dbEstabItem.getDescription()));
					DatabaseHelper.getDatabaseInstance(context).insertarEstablecimiento(establecimiento);					
				}
				idEstab = DatabaseHelper.getDatabaseInstance(context).getIdEstablecimiento(dbEstabItem.getName());
				
				for (DispositivoVO servDispItem : dbEstabItem.dispositivos) {
					Log.d("Disp", servDispItem.getName().toString());
					if (!existeDispositivo(context, new SpannableStringBuilder(servDispItem.getName()))){
						dispositivo = new Dispositivo(idEstab, new SpannableStringBuilder(servDispItem.getName()), new SpannableStringBuilder(servDispItem.getDescription()));
						DatabaseHelper.getDatabaseInstance(context).insertarDispositivo(dispositivo);
					}
				}
			}
			return true;
		}
		return false;
	}
	//public final static String CobrAppUserName = "super";
	//public final static String CobrAppPassword = "123456";
	public final static String apiURL = "http://200.127.26.126:8108/cobrappapi/api/";
	public InputStreamReader getFromServer()
	{	
		HttpResponse httpResponse;
		
		InputStreamReader response = null;
			
		HttpClient httpclient = new DefaultHttpClient();  
		
        try 
        {  
        	httpResponse = httpclient.execute(new HttpGet(apiURL+ "establecimiento/list"));
            
            response = new InputStreamReader(httpResponse.getEntity().getContent(), "UTF-8");
        } 
        catch (ClientProtocolException e) 
        {  
            e.printStackTrace();  
        } 
        catch (IOException e) 
        {  
            e.printStackTrace();  
        }  
        
        return response;
	}
	
	public class EstablecimientoVO
	{
		private String name;
		private String description;
		private ArrayList<DispositivoVO> dispositivos;
		
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getDescription() {
			return description;
		}
		public void setDescription(String description) {
			this.description = description;
		}
		public ArrayList<DispositivoVO> getDispositivos() {
			return dispositivos;
		}
		public void setDispositivos(ArrayList<DispositivoVO> dispositivos) {
			this.dispositivos = dispositivos;
		}
		
	}
	public class DispositivoVO
	{
		private String name;
		private String description;
		
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getDescription() {
			return description;
		}
		public void setDescription(String description) {
			this.description = description;
		}
	}
	
	
}
